
#include "drv_uart.h"

/*  connect EVB_ARDO evaluation board  J6 to computer terminal by  mini-usb  */

uint8_t intflag = 0;
uint8_t ch;


//#define UART_RX_DMA
/* gauDMATransferBuff data storage address */
#pragma location = 0x20000000
 uint8_t gauDMATransferBuff[0x400] = {0x51, 0x52, 0x53, 0x54,0x55,0x56,0x57,0x58,0x55};



void uart_cbf()
{
    /* receive data */
    ch = UART_ReceiveByte(UART1_ID);
    
    intflag = 1;
}


void Ex_Uart_Init(void){
    UART_Config_t tUartCfgStruct = 
    {
        2000000,                 /* buard rate */
        UART_DATABITS_8,         /* data size */
        UART_PARITY_NONE,        /* parity */
        UART_STOPBITS_1,         /* stop bit */
        DISABLE,                 /* flow control */
        40000000                 /* function clock freq */
    };
    
    
    /* choose osc clock as function clock of uart1 */
    CLK_ModuleSrc(CLK_UART1, CLK_SRC_OSC40M);
    /* set divide ratio of uart1's function clock*/
    CLK_SetClkDivider(CLK_UART1, CLK_DIV_1);  
    /* enable clock for uart1 */
    SYSCTRL_EnableModule(SYSCTRL_UART1);  
    
    /*When UART re-open after close, need to check and clear busy status*/
    while(ERR == UART_WaitBusyClear(UART1_ID, 7000))
    {
        (void)UART_ReceiveByte(UART1_ID);
    }
    
    /* initiate uart1 */
    UART_Init(UART1_ID, &tUartCfgStruct);
    
    /* fifo config */
    const UART_FIFOConfig_t fifoCfg = 
    { 
        //ENABLE, ENABLE, ENABLE, UART_TX_FIFO_HALF, UART_RX_FIFO_CHAR_1 
        ENABLE, ENABLE, ENABLE, UART_TX_FIFO_QUARTER, UART_RX_FIFO_CHAR_1 
    }; 
    
    
    UART_FIFOConfig(UART1_ID, &fifoCfg);
    
    /* choose osc clock as function clock of portd */
    CLK_ModuleSrc(CLK_PORTC, CLK_SRC_OSC40M);   
    /* enable clock for portd */
    SYSCTRL_EnableModule(SYSCTRL_PORTC);    
    
    /* ptc7: , uart tx */
    PORT_PinmuxConfig(PORT_C, GPIO_7, PTC7_UART1_TX); 
    /* ptc6:  uart rx */
    PORT_PinmuxConfig(PORT_C, GPIO_6, PTC6_UART1_RX); 
    
    
    /* callback function */
    //UART_InstallCallBackFunc(UART1_ID, UART_INT_RBFI, uart_cbf);
    
    /* enable received data available interrupt  */
    //UART_IntMask(UART1_ID, UART_INT_RBFI, UNMASK);

    /* enable IRQ */
    //NVIC_EnableIRQ(UART1_IRQn);
    
}


void DMATEST_TransferConfig(void)
{
#ifndef UART_RX_DMA
    DMA_TransferConfig_t gtDMATransferConfig0;
    /* the channe0 used for dma transfer */
    gtDMATransferConfig0.channel = DMA_CHANNEL15;
    /* DMA channel priority  */
    gtDMATransferConfig0.channelPriority = DMA_CHN_PRIORITY15;
    /* the source of the DMA request for this channe0 */
    gtDMATransferConfig0.source = DMA_REQ_UART1_TX;
    /* done interrupt mask */
    gtDMATransferConfig0.doneIntMask = MASK;
    /* error interrupt mask */
    gtDMATransferConfig0.errorIntMask = MASK;
    
    /* address pointing to the source data */
    gtDMATransferConfig0.srcAddr = (uint32_t)gauDMATransferBuff;
    /* address pointing to the destination data */
    gtDMATransferConfig0.destAddr = (uint32_t)0x4006B000; /* UART1 ADD THD */
    
    
    /* source address offset */
    gtDMATransferConfig0.minorLoopSrcOffset = 1;    /* addition mode  */
    /* destination address offset */
    gtDMATransferConfig0.minorLoopDestOffset = 0;   /* destination should not change */
    
    /* source address offset after a major loop done */
    gtDMATransferConfig0.majorLoopSrcOffset = -256;
    /* destination address offset after a major loop done */
    gtDMATransferConfig0.majorLoopDestOffset = 0;
    
    /* source data transfer size */
    gtDMATransferConfig0.srcTransferSize = DMA_TRANSFER_SIZE_1B;
    /* destintion data transfer size, uart buffer is 8 bits, tramsfer size is better no larger than 1 byte */
    gtDMATransferConfig0.destTransferSize = DMA_TRANSFER_SIZE_1B;
    
    /* transfer bytes number */
    gtDMATransferConfig0.transferByteNum = 0x100;       /* send byte num */
    /* number of minor loop in a major loop */
    gtDMATransferConfig0.minorLoopNum = 1;          /* repeat send msg times */
    /* disable request after done control */
    gtDMATransferConfig0.disableRequestAfterDoneCmd = ENABLE;
    
    /* dma transfer config Function */
    DMA_ConfigTransfer(&gtDMATransferConfig0);

#else
    DMA_TransferConfig_t gtDMATransferConfig1;
    /* the channe1 used for dma transfer */
    gtDMATransferConfig1.channel = DMA_CHANNEL1;
    /* DMA channel priority  */
    gtDMATransferConfig1.channelPriority = DMA_CHN_PRIORITY1;
    /* the source of the DMA request for this channe1 */
    gtDMATransferConfig1.source = DMA_REQ_UART1_RX;
    /* done interrupt mask */
    gtDMATransferConfig1.doneIntMask = MASK;
    /* error interrupt mask */
    gtDMATransferConfig1.errorIntMask = MASK;
    
    /* source address offset */
    gtDMATransferConfig1.srcAddr = (uint32_t)0x4006B000;
    /* destination address offset */
    gtDMATransferConfig1.destAddr = (uint32_t)gauDMATransferBuff + 0x10;
    /* source data transfer size */
    gtDMATransferConfig1.minorLoopSrcOffset = 0;
    /* destintion data transfer size */
    gtDMATransferConfig1.minorLoopDestOffset = 1;
    /* source address offset after a major loop done */
    gtDMATransferConfig1.majorLoopSrcOffset = 0;
    /* destination address offset after a major loop done */
    gtDMATransferConfig1.majorLoopDestOffset = 0;
    /* source data transfer size */
    gtDMATransferConfig1.srcTransferSize = DMA_TRANSFER_SIZE_1B;
    /* destintion data transfer size */
    gtDMATransferConfig1.destTransferSize = DMA_TRANSFER_SIZE_1B;
    /* transfer bytes number */
    gtDMATransferConfig1.transferByteNum = 4;
    /* number of minor loop in a major loop */
    gtDMATransferConfig1.minorLoopNum = 1;
    /* disable request after done control */
    gtDMATransferConfig1.disableRequestAfterDoneCmd = ENABLE;
    
    /* dma transfer config Function */
    DMA_ConfigTransfer(&gtDMATransferConfig1);
    
#endif
}


void Ex_Dma_Init(void){
    
     DMA_Config_t gtDMAInitConfig;
    
     /* enable  DMA */
    SYSCTRL_EnableModule(SYSCTRL_DMA);
    SYSCTRL_EnableModule(SYSCTRL_DMAMUX);
    
    
    /* dma behavior in debiug mode */
    gtDMAInitConfig.dmaDebugBehavior = DMA_DEBUG_HALT;
    /* dma behavior in error mode */
    gtDMAInitConfig.dmaErrorBehavior = DMA_ERROR_HALT;
    /* dma priority arbitration */
    gtDMAInitConfig.dmaPriorityArbitration = DMA_ROUND_ROBIN_ARBITRATION;
    /* initializes dma */
    DMA_Init(&gtDMAInitConfig);

    /* DMA transfer config */
    DMATEST_TransferConfig();
    
    
#ifdef UART_RX_DMA
    /* transmit data by terminal such as 0x44, 0x33, 0x22, 0x11 */
    /* enable dma channe0 request Function */
    DMA_ChannelRequestEnable(DMA_CHANNEL1);

    /* DMA should be halted when refereshing or unlock wdog, and after that continuing DMA transfer*/
    DMA_HaltControl(ENABLE);
    WDOG_Refresh();
    DMA_HaltControl(DISABLE);

    /* Wait for DONE flag bit of DMA channel hardware request status Register to be set */
    while (DMA_GetDoneStatus(DMA_CHANNEL1) != SET);
#else
//    DMA_ChannelRequestEnable(DMA_CHANNEL0);

//    /* DMA should be halted when refereshing or unlock wdog, and after that continuing DMA transfer*/
//    DMA_HaltControl(ENABLE);
//    WDOG_Refresh();
//    DMA_HaltControl(DISABLE);

//    while (DMA_GetDoneStatus(DMA_CHANNEL0) != SET);
#endif
}


void Ex_Uart_Dma_Init(void){
    
    
    /* enable  DMA */
    SYSCTRL_EnableModule(SYSCTRL_DMA);
    SYSCTRL_EnableModule(SYSCTRL_DMAMUX);
    
    
    Ex_Uart_Init();
    
    Ex_Dma_Init();
    
    for(unsigned int i = 0x00U;i< 0x400;i++){
        
        gauDMATransferBuff[i] = i;
    
    }
}